package beans;

import db_connect.DB;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpSession;
import org.apache.myfaces.custom.calendar.HtmlInputCalendar;

/**
 *
 * @author Milan Boricic <boricic@gmail.com>
 */
public class Korisnik {

    public static final String ACTION_KORISNIK = "korisnik";
    public static final String ACTION_ADMIN = "admin";

    private Integer kid;
    private String username;
    private String lozinka;
    private String reLozinka;
    private String ime;
    private String prezime;
    private String email;
    private String funkcija;
    private boolean isAdmin;

    private String outcome;

    private Sala izabrana;
    private Korisnik izabraniKorisnik;
    private HtmlInputCalendar cal;
    private Date datum = new Date(System.currentTimeMillis());
    private List<Dan> dani;
    private Termin termin;
    private String searchText;
    

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getFunkcija() {
        return funkcija;
    }

    public void setFunkcija(String funkcija) {
        this.funkcija = funkcija;
    }

    public String getIme() {
        return ime;
    }

    public void setIme(String ime) {
        this.ime = ime;
    }

    public boolean isIsAdmin() {
        return isAdmin;
    }

    public void setIsAdmin(boolean isAdmin) {
        this.isAdmin = isAdmin;
    }

    public Integer getKid() {
        return kid;
    }

    public void setKid(Integer kid) {
        this.kid = kid;
    }

    public String getLozinka() {
        return lozinka;
    }

    public void setLozinka(String lozinka) {
        this.lozinka = lozinka;
    }

    public String getPrezime() {
        return prezime;
    }

    public void setPrezime(String prezime) {
        this.prezime = prezime;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getOutcome() {
        return outcome;
    }

    public void setOutcome(String outcome) {
        this.outcome = outcome;
    }

    public Korisnik getIzabraniKorisnik() {
        return izabraniKorisnik;
    }

    public void setIzabraniKorisnik(Korisnik izabraniKorisnik) {
        this.izabraniKorisnik = izabraniKorisnik;
    }
    
    public String login() {
        Connection con = null;
        Statement stmt = null;
        ResultSet rs = null;
        FacesContext context = FacesContext.getCurrentInstance();

        try {
            con = DB.getConnection();
            stmt = con.createStatement();
            String query = "select * from korisnik where username='" + username +
                    "' and lozinka='" + lozinka + "';";
            rs = stmt.executeQuery(query);
            if (rs.next()) {
                kid = rs.getInt("kid");
                ime = rs.getString("ime");
                prezime = rs.getString("prezime");
                email = rs.getString("email");
                funkcija = rs.getString("funkcija");
                isAdmin = rs.getBoolean("isAdmin");

                cal = new HtmlInputCalendar();
                cal.setValue(datum);
                
                if(isAdmin) {
                    setOutcome(ACTION_ADMIN);
                } else {
                    setOutcome(ACTION_KORISNIK);
                }
                
                return outcome;
            } else {
                context.addMessage(null, new FacesMessage("Neispravni korisničko ime i lozinka!"));
            }

            stmt.close();
            con.close();
        } catch(SQLException sqle) {
            setOutcome("error");
            sqle.printStackTrace();
            if (con != null) {
                try {
                    con.close();
                } catch (Exception exc) {
                }
            }
        }

        return isAdmin ? ACTION_ADMIN : ACTION_KORISNIK;
    }

    public Sala getIzabrana() {
        return izabrana;
    }

    public void setIzabrana(Sala izabrana) {
        this.izabrana = izabrana;
    }

    public HtmlInputCalendar getCal() {
        return cal;
    }

    public void setCal(HtmlInputCalendar cal) {
        this.cal = cal;
    }
    
    public String kpocetna() {
        setOutcome(ACTION_KORISNIK);
        return outcome;
    }

    public String aPocetna() {
        setOutcome(ACTION_ADMIN);
        return outcome;
    }

    public Date getDatum() {
        return datum;
    }

    public void setDatum(Date datum) {
        this.datum = datum;
    }

    public List<Dan> getDani() {
        return dani;
    }

    public void setDani(List<Dan> dani) {
        this.dani = dani;
    }

    public Termin getTermin() {
        return termin;
    }

    public void setTermin(Termin termin) {
        this.termin = termin;
    }
    
    
    public String calChange(ValueChangeEvent event) {
        datum = (Date) event.getNewValue();
        String result = rasporedRefresh();
        return result;
    }

    public String getReLozinka() {
        return reLozinka;
    }

    public void setReLozinka(String reLozinka) {
        this.reLozinka = reLozinka;
    }

    public String getSearchText() {
        return searchText;
    }

    public void setSearchText(String searchText) {
        this.searchText = searchText;
    }
    
    public String rasporedRefresh() {
        
        Calendar newCal = new GregorianCalendar();
        newCal.setTime(datum);

        int day = newCal.get(Calendar.DAY_OF_WEEK);
        int fromMonday = day - Calendar.MONDAY;

        Calendar monday = new GregorianCalendar();
        monday.setTime(datum);
        monday.set(Calendar.DAY_OF_MONTH, newCal.get(Calendar.DAY_OF_MONTH) - fromMonday);

        dani = new ArrayList<Dan>(5);

        for (int i = Calendar.MONDAY; i <= Calendar.FRIDAY; i++) {
            Dan dan = new Dan();
            Calendar tmpDate = new GregorianCalendar();
            tmpDate.setTime(monday.getTime());
            tmpDate.set(Calendar.DAY_OF_MONTH, monday.get(Calendar.DAY_OF_MONTH) + i - Calendar.MONDAY);
            dan.setDatum(tmpDate.getTime());
            dan.setNaziv(dan.getImeDana(tmpDate.get(Calendar.DAY_OF_WEEK)));

            NeradniDan neradan = NeradniDan.getDatumNeradan(izabrana, tmpDate.getTime());
            dan.setNeradan(neradan);

            ArrayList<Termin> termini = new ArrayList<Termin>();
            for (int j = 0; j + 8 <= 21; j++) {
                Termin termin = new Termin();
                Calendar tmpCal = new GregorianCalendar();
                tmpCal.set(Calendar.HOUR_OF_DAY, j + 8);
                tmpCal.set(Calendar.MINUTE, 0);
                tmpCal.set(Calendar.MILLISECOND, 0);
                tmpCal.set(0, 0, 0);
                Time tmpTime = new Time(tmpCal.getTimeInMillis());
                termin.setVreme(tmpTime);
                termin.setDan(dan);
                termini.add(termin);
            }
            dan.setTermini(termini);
            dani.add(dan);
        }


        for (Dan d : dani) {
            java.sql.Date date = new java.sql.Date(d.getDatum().getTime());
            List<Rezervacija> rezervacije = Rezervacija.getRezervacijeByDate(izabrana, date);
            for (Termin t : d.getTermini()) {
                for (Rezervacija r : rezervacije) {
                    Calendar tmpCal = new GregorianCalendar();
                    tmpCal.setTimeInMillis(r.getPocevOd().getTime());
                    tmpCal.set(0, 0, 0);
                    tmpCal.set(Calendar.MINUTE, 0);
                    tmpCal.set(Calendar.MILLISECOND, 0);
                    Time rezVreme = new Time(tmpCal.getTimeInMillis());
                    tmpCal.set(Calendar.HOUR_OF_DAY, tmpCal.get(Calendar.HOUR_OF_DAY) + r.getTrajanje());
                    tmpCal.set(Calendar.MINUTE, 0);
                    tmpCal.set(Calendar.MILLISECOND, 0);
                    Time rezVremeKraj = new Time(tmpCal.getTimeInMillis());

                    if (t.getVreme().equals(rezVreme) || (t.getVreme().after(rezVreme) && t.getVreme().before(rezVremeKraj)) ) {
                        t.setRezervacija(r);
                        t.setZauzet(true);
                    }
                }
            }
        }
        return isAdmin ? ACTION_ADMIN : ACTION_KORISNIK;
    }

    public List getSviKorisnici() {
        List<Korisnik> korisnici = new ArrayList<Korisnik>();
        Connection con = null;
        Statement stmt = null;
        ResultSet rs = null;

        try {
            con = DB.getConnection();
            stmt = con.createStatement();
            String query = null;
            if (searchText == null || "".equals(searchText)) {
                query = "select * from korisnik;";
            } else {
                query = "select * from korisnik where ime like '%"+searchText+"%' or prezime like '%"+searchText+"%';";
            }
            rs = stmt.executeQuery(query);
            while(rs.next()) {
                Korisnik korisnik = new Korisnik();
                korisnik.setKid(rs.getInt("kid"));
                korisnik.setIme(rs.getString("ime"));
                korisnik.setUsername(rs.getString("username"));
                korisnik.setPrezime(rs.getString("prezime"));
                korisnik.setEmail(rs.getString("email"));
                korisnik.setFunkcija(rs.getString("funkcija"));
                korisnik.setIsAdmin(rs.getBoolean("isAdmin"));

                korisnici.add(korisnik);
            }

            stmt.close();
            con.close();
        } catch(SQLException sqle) {
            sqle.printStackTrace();
            if (con != null) {
                try {
                    con.close();
                } catch (Exception exc) {
                }
            }
        }
        return korisnici;
    }

    public String rezervisi() {
        setOutcome("rezervacija");
        return ACTION_KORISNIK;
    }

    public String pregled() {
        setOutcome("pregled");
        return ACTION_KORISNIK;
    }

    public String rezervisi2() {
        String result = null;
        Termin ter = getTermin();
        Rezervacija rez = ter.getRezervacija();

        try {
            SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.mm.yyyy.");
            rez.setDatum(new java.sql.Date(dateFormatter.parse(ter.getDan().getDatumString()).getTime()));

            SimpleDateFormat timeFormatter = new SimpleDateFormat("H");
            rez.setPocevOd(new Time(timeFormatter.parse(ter.getVremeString()).getTime()));

        } catch (ParseException ex) {
            Logger.getLogger(Rezervacija.class.getName()).log(Level.SEVERE, null, ex);
        }

        rez.setDatumRezervisanja(new Timestamp(System.currentTimeMillis()));
        rez.setKorisnik(this);
        rez.setSala(getIzabrana());

        return result;
    }

    public String aDodajKorisnika() {
        setOutcome("dodaj_korisnika");
        return ACTION_ADMIN;
    }

    public String aPregledLaboratorija() {
        setOutcome("pregled_laboratorija");
        return ACTION_ADMIN;
    }

    public String aZahteviRegistracije() {
        setOutcome("zahtevi_registracije");
        return ACTION_ADMIN;
    }

    public String neradniDani() {

        setOutcome("neradni_dani");
        return ACTION_ADMIN;
    }

    public String aViewKorisnici() {
        setOutcome("korisnici");
        return ACTION_ADMIN;
    }

    public String logout() {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
        session.invalidate();
        return "logout";
    }

    public String aViewKorisnikInformacije() {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
        Korisnik kor = (Korisnik) session.getAttribute("korisnik");

        kor.setIzabraniKorisnik(this);
        return kor.viewKorisnikInformacije();

    }
    
    public String viewKorisnikInformacije() {
        setOutcome("korisnik_info");
        return ACTION_ADMIN;
    }

    public String aViewKorisnikRezervacije() {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
        Korisnik kor = (Korisnik) session.getAttribute("korisnik");

        kor.setIzabraniKorisnik(this);
        return kor.viewKorisnikRezervacije();

    }

    public String viewKorisnikRezervacije() {
        setOutcome("korisnik_rezervacije");
        return ACTION_ADMIN;
    }

    public List getRezervacijeByIzabraniKorisnik() {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
        Korisnik kor = (Korisnik) session.getAttribute("korisnik");
        return (new Rezervacija()).getRezervacijeByKorisnikParam(kor.getIzabraniKorisnik());
    }

    public String aDeleteKorisnik() {
        Connection con = null;
        Statement stmt = null;
        FacesContext context = FacesContext.getCurrentInstance();

        try {
            con = DB.getConnection();
            stmt = con.createStatement();
            String query = "delete from rezervacija where korisnik = " + kid + ";";
            stmt.executeUpdate(query);

            query = "delete from korisnik where kid = " + kid + ";";
            stmt.executeUpdate(query);
            context.addMessage(null, new FacesMessage("Korisnik uspešno obrisan"));

            stmt.close();
            con.close();
        } catch(SQLException sqle) {
            sqle.printStackTrace();
            if (con != null) {
                try {
                    con.close();
                } catch (Exception exc) {
                }
            }
        }

        return ACTION_ADMIN;
    }

    public String aViewRezervisiZa() {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) context.getExternalContext().getSession(false);
        Korisnik kor = (Korisnik) session.getAttribute("korisnik");

        kor.setIzabraniKorisnik(this);
        return kor.viewRezervisiZa();
    }

    public String viewRezervisiZa() {
         setOutcome("korisnik");
         return ACTION_ADMIN;
    }
    
}
